import entity.Person;
import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @author zk
 * @Description: Class类
 * @date 2019-10-27 12:15
 */
public class ClassDemo {

    @Test
    public void getClassFunction() throws ClassNotFoundException{
        //类的全名字符串
        Class<?> aClass = Class.forName("java.lang.String");
        Object obj = new Person();
        //对象.getClass()
        Class<?> cClass = obj.getClass();
        //类.class
        Class<String> bClass = String.class;
    }

    @Test
    public void classInner() throws ClassNotFoundException {

        //根据类的全名获取类的对象
        Class<?> clazz = Class.forName("java.lang.String");

        //获取所有方法，幷打印
        Method[] methods = clazz.getMethods();
        Arrays.stream(methods).forEach(System.out::println);

        System.out.println("================================");

        //获取所有属性，幷打印
        Field[] fields = clazz.getFields();
        Arrays.stream(fields).forEach(System.out::println);

        System.out.println("================================");

        //获取所有构造器，幷打印
        Constructor[] constructors = clazz.getConstructors();
        Arrays.stream(constructors).forEach(System.out::println);

        System.out.println("================================");

    }

    @Test
    public void classInner2() throws NoSuchFieldException, NoSuchMethodException {
        Class<Person> clazz = Person.class;

        //获取指定属性,注意：getField只能获取公共的属性，若需要获取非公共的的属性则调用getDeclaredField,
        //下面获取方法、构造器也是如此，调用带有declared的方法就可以获取已申明的属性、方法或者构造器等
        Field name = clazz.getField("country");
        System.out.println(name);

        //获取指定方法
        Method method = clazz.getMethod("setName",String.class);
        System.out.println(method);

        //获取指定购置器
        Constructor constructor = clazz.getConstructor(String.class,String.class,Integer.class);
        System.out.println(constructor);

    }

    @Test
    public void constructorTest() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException,
            InstantiationException {
        Class clazz = Person.class;
        Constructor  constructor = clazz.getConstructor();
        Object obj = constructor.newInstance();
        System.out.println(obj);
    }

    @Test
    public void createInstanceTest() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException,
            InstantiationException, ClassNotFoundException, NoSuchFieldException {
        Class clazz = Class.forName("entity.Person");
        Constructor<?> constructor = clazz.getDeclaredConstructor();
        Object obj = constructor.newInstance();
        System.out.println(obj);
        for (Method m :
                clazz.getMethods()) {
            String mName = m.getName();
            if(mName.startsWith("set")){
                String fieldName = mName.substring(3);
                fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
                Field field = clazz.getDeclaredField(fieldName);
                Class<?> fieldType = field.getType();
                if(String.class == fieldType && fieldName.equals("name")){
                    m.invoke(obj, "张三");
                } else if (String.class == fieldType && fieldName.equals("sex")){
                    m.invoke(obj, "男");
                } else if (Integer.class == fieldType){
                    m.invoke(obj,18);
                }
            }
        }

        System.out.println(obj);
    }


}
